﻿//=================================================================
// Copyright © 2006 Microsoft Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//==================================================================
// Project    : Gaee WebFramework
// Description: 
// 系统调用界面类
//  Change History:
//  When        Who         Why
//----------------------------------------------------------------
//  2011/06/28  Julian.Hu     Created. 
//
// © 2010-2011 Microsoft
// All Rights Reserved
//----------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GaeaWebFramework.Facade;
using System.Runtime.Serialization;
using System.Xml;
using GaeaWebFramework.Common;
using GaeaWebFramework.Common.Biz;
using System.Reflection;
using Titan.Serialization;


namespace GaeaWebFramework.Facade.Impl
{
    public sealed class FacadeRuntime:IFacadeRuntime
    {
        /// <summary>
        /// 
        /// </summary>
        class AssemblyInfo
        {
            public string ID;
            public string filename;
            public string classname;
            public string codeprefix;
            public Assembly instance;
        }
        #region fields
        private List<AssemblyInfo> modulelist = new List<AssemblyInfo>();
        #endregion

        #region methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="username"></param>
        /// <param name="macaddress"></param>
        /// <param name="computername"></param>
        /// <returns></returns>
        private bool doBizFireWall(string username, string macaddress, string computername)
        {
            bool result = true;
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        private void doLoadBizRouteTable()
        { 
            //DONE check Route Table in cache or not
            //DONE get Route Table from cache
            //DONE get Route Table from XML file
            //DONE save Route Table into cache

            if (CommVars.cachemanager.Has("AssemblyCache"))
            {
                modulelist = CommVars.cachemanager.Get<List<AssemblyInfo>>("AssemblyCache");
            }
            else
            {
                XmlDocument xml = new XmlDocument();
                xml.Load(@".\Addin\BizRouteTable.Addin");
                IntfAddinTemplates templates = SerializeUtils.Deserialize<IntfAddinTemplates>(xml.OuterXml);

                foreach (IntfAddinModules modules in templates.Modules)
                {
                    foreach (InftAddinModuleItem item in modules.Items)
                    {
                        try
                        {
                            AssemblyInfo assembly = new AssemblyInfo();
                            assembly.ID = item.ID;
                            assembly.filename = item.File;
                            assembly.classname = item.ModuleClass;
                            assembly.codeprefix = item.CodePrefix;
                            assembly.instance = Assembly.LoadFile(item.File);
                            modulelist.Add(assembly);
                        }
                        catch (Exception ex)
                        {
                            System.Console.WriteLine(ex.Message);
                        }
                    }
                }

                CommVars.cachemanager.Set<List<AssemblyInfo>>("AssemblyCache", modulelist);
            }
     
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fid"></param>
        /// <returns></returns>
        private string doFindModuleNameByFID(int fid)
        {
            string result = "";
            foreach (AssemblyInfo info in modulelist)
            {
                int codeprefix = fid / CommConsts.FUNCTION_CODE_LEN;
                if (info.codeprefix==Convert.ToString(codeprefix))
                {
                    result = info.ID;
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="modulename"></param>
        /// <returns></returns>
        private AssemblyInfo doFindModuleByName(string modulename)
        {
            AssemblyInfo result = null ;
            foreach(AssemblyInfo info in modulelist)
            {
                if (info.ID == modulename)
                {
                    result = info;
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        private void doLoadBizFirewallRules()
        {
            //TODO check Rule table in cache or not
            //TODO get rule table from cache
            //TODO get rule table from xml
            //TODO save rule table into cache
        }

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fid"></param>
        /// <param name="iClientInfo"></param>
        /// <param name="iParam"></param>
        /// <param name="oParam"></param>
        /// <returns></returns>
        public bool RouteFunction(int fid, ClientInfo iClientInfo, XmlDocument iParam, out XmlDocument oParam)
        {
            bool result = false;

            doLoadBizFirewallRules();
            doLoadBizRouteTable();

            string username = ((ClientInfo)iClientInfo).UserName;
            string ipaddress = ((ClientInfo)iClientInfo).IPAddres;
            string macaddress = ((ClientInfo)iClientInfo).MacAddress;
            string computername = ((ClientInfo)iClientInfo).ComputerName;

            try
            {
                result = doBizFireWall(username, macaddress, computername);
                if (!result)
                {
                    throw new FacadeException("");
                }

                //load biz logic modules
                //DONE calculate bizmodule name from configure file
                //DONE calculate bizmodule object name from configure file

                string modulename = doFindModuleNameByFID(fid);
                if (modulename == "")
                {
                    throw new FacadeException("");
                }

                AssemblyInfo bizmoduleinfo = doFindModuleByName(modulename);
                if (bizmoduleinfo == null)
                {
                    throw new FacadeException("");
                }
                Assembly bizmodule = bizmoduleinfo.instance;
                if (bizmodule == null)
                {
                    throw new FacadeException("");
                }
                IBizRuntime obj = (IBizRuntime)bizmodule.CreateInstance(bizmoduleinfo.classname);
                if (obj == null)
                {
                    throw new FacadeException("");
                }
               
                result=obj.hasFunction(fid);
                
                if (!result)
                {
                    throw new FacadeException("");
                }

                object output;

                result = obj.RunFunction(fid, iParam, out output);
            }
            catch (FacadeException ex)
            {
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.Message);
            }
            oParam = null;
            return result;
        }
        #endregion

        #region events
        #endregion


    }
}
